home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 5 / Apprentice-Release5.iso / Source Code / C / Applications / Python 1.3.3 / Python 133 SRC / Demo / www / waislib.py < prev    next >
Text File  |  1996-03-12  |  4KB  |  171 lines

  1. # WAIS client interface, based on the waisq model.
  2. # This accurately parses the waisq question file, so no surprises!
  3. # (XXX But the parser is too slow...)
  4.  
  5.  
  6. import waisqp
  7. import tempfile
  8. import os
  9.  
  10.  
  11. # The waisq program.  XXX Rely on user's $PATH
  12. WAISQ = 'waisq -c /ufs/guido/src/wais/wais-sources/'
  13.  
  14.  
  15. # Question class.  Normal usage:
  16. # >>> q = Question()
  17. # >>> q.set_seed_words('some interesting phrase')
  18. # >>> q.add_source('foobar.src')
  19. # >>> ...
  20. # >>> q.do_query()
  21. # >>> for x in q.get_result_summary(): print x
  22. # To print document number i (0 <= i < number-of-documents):
  23. # >>> q.write_document(i, sys.stdout)
  24. # or, e.g.:
  25. # >>> q.pipe_document(i, '/usr/ucb/more')
  26. # or:
  27. # >>> print q.get_document(i)
  28. #
  29. class Question:
  30.     #
  31.     def __init__(self):
  32.         self.seed_words = ''
  33.         self.sources = []
  34.         self.relevant_documents = waisqp.List()
  35.         self.result_documents = waisqp.List()
  36.         self.scratch = tempfile.mktemp()
  37.     #
  38.     def close(self):
  39.         try:
  40.             os.unlink(self.scratch)
  41.         except os.error:
  42.             pass
  43.     #
  44.     def set_seed_words(self, seed_words):
  45.         self.seed_words = seed_words
  46.     #
  47.     def get_seed_words(self):
  48.         return self.seed_words
  49.     #
  50.     def add_source(self, source):
  51.         self.sources.append(source)
  52.     #
  53.     def reset_sources(self):
  54.         self.sources = []
  55.     #
  56.     def get_sources(self):
  57.         return self.sources
  58.     #
  59.     def get_result_documents(self):
  60.         return self.result_documents
  61.     #
  62.     def do_query(self):
  63.         qrec = waisqp.Record('question')
  64.         qrec['version'] = '2'
  65.         qrec['seed-words'] = '"' + self.seed_words + '"'
  66.         qrec['relevant-documents'] = self.relevant_documents
  67.         slist = waisqp.List()
  68.         for source in self.sources:
  69.             s = waisqp.Record('source-id')
  70.             s['filename'] = '"' + source + '"'
  71.             slist.append(s)
  72.         qrec['sources'] = slist
  73.         file = self.scratch
  74.         f = open(file, 'w')
  75.         f.write(`qrec`)
  76.         f.close()
  77.         sts = os.system(WAISQ + ' -f ' + file + ' -g; echo 1>&2\n')
  78.         if sts != 0:
  79.             raise RuntimeError, 'waisq exit status ' + `sts`
  80.         record = waisqp.parsefile(file)
  81.         if record.gettype() <> 'question':
  82.             raise RuntimeError, 'waisq did not write a question'
  83.         self.result_documents = record['result-documents']
  84.     #
  85.     def get_result_summary(self):
  86.         summary = []
  87.         for doc in self.result_documents:
  88.             score = doc['score']
  89.             doc = doc['document']
  90.             headline = doc['headline']
  91.             lines = doc['number-of-lines']
  92.             bytes = doc['number-of-bytes']
  93.             type = doc['type']
  94.             date = doc['date']
  95.             rec = score, headline, lines, bytes, type, date
  96.             summary.append(rec)
  97.         return summary
  98.     #
  99.     def get_document(self, i):
  100.         if not 0 <= i < len(self.result_documents):
  101.             raise IndexError, 'document number out of range'
  102.         cmd = WAISQ + ' -f ' + self.scratch + ' -v ' + `i+1` + '\n'
  103.         p = os.popen(cmd, 'r')
  104.         data = p.read()
  105.         sts = p.close()
  106.         if sts:
  107.             sys.stderr.write('waisq exit status ' + `sts` + '\n')
  108.         return data
  109.     #
  110.     def pipe_document(self, i, backend):
  111.         if not 0 <= i < len(self.result_documents):
  112.             raise IndexError, 'document number out of range'
  113.         cmd = WAISQ + ' -f ' + self.scratch + ' -v ' + `i+1`
  114.         cmd = cmd + ' | ' + backend + '\n'
  115.         sts = os.system(cmd)
  116.         if sts:
  117.             sys.stderr.write('pipe_document exit status ' + \
  118.                 `sts` + '\n')
  119.     #
  120.     def write_document(self, i, f, *rest):
  121.         if rest:
  122.             if len(rest) > 1: raise TypeError, 'too many arguments'
  123.             bufsize = rest[0]
  124.         else:
  125.             bufsize = 8192
  126.         if not 0 <= i < len(self.result_documents):
  127.             raise IndexError, 'document number out of range'
  128.         cmd = WAISQ + ' -f ' + self.scratch + ' -v ' + `i+1` + '\n'
  129.         p = os.popen(cmd, 'r')
  130.         while 1:
  131.             buf = p.read(bufsize)
  132.             if not buf: break
  133.             f.write(buf)
  134.         sts = p.close()
  135.         if sts:
  136.             sys.stderr.write('waisq exit status ' + `sts` + '\n')
  137.  
  138.  
  139. # Test program.
  140. # usage: python -c 'import waislib;waislib.test()' database word ...
  141. #
  142. def test():
  143.     import sys, string
  144.     if len(sys.argv) < 3:
  145.         sys.stderr.write('usage: test database word ...\n')
  146.         sys.exit(2)
  147.     db = sys.argv[1]
  148.     if db[-4:] <> '.src': db = db + '.src'
  149.     q = Question()
  150.     try:
  151.         q.add_source(db)
  152.         q.set_seed_words(string.join(sys.argv[2:]))
  153.         q.do_query()
  154.         K = 1024
  155.         i = 0
  156.         summary = q.get_result_summary()
  157.         for rec in summary:
  158.             score, headline, lines, bytes, type, date = rec
  159.             bytes = eval(bytes)
  160.             print i+1, score, `(bytes+K-1)/K` + 'K', type, date, \
  161.                 headline
  162.             reply = raw_input('retrieve this document? [yn](n) ')
  163.             if string.lower(string.strip(reply)[:1]) == 'y':
  164.                 if summary[i][4] == '"MIME"':
  165.                     q.pipe_document(i, 'metamail')
  166.                 else:
  167.                     q.pipe_document(i, '${PAGER-more}')
  168.             i = i+1
  169.     finally:
  170.         q.close()
  171.